perm filename TCPPRC.MAC[IP,SYS] blob
sn#680227 filedate 1982-10-14 generic text, type T, neo UTF8
;CWL:<403-TCP>TCPPRC.MAC.40303 26-Apr-82 17:32:47, Edit by CLYNN
; Remove section 0 restriction on BG and IP; More error returns
;<403-TCP>TCPPRC.MAC.40301 29-Jan-82 15:06:54, Edit by CLYNN
; Updated for TCP release 3
; TCPCKT in STG is check interval
;[BBNF]<401-TCP>TCPPRC.MAC.18, 10-Jul-81 16:12:00, Ed: CLYNN
; Fix: Error returns from initialization routines
SEARCH INPAR,TCPPAR,PROLOG
TTITLE TCPPRC
SUBTTL TCP Process, William W. Plummer, 1Mar79
COMMENT !
This is the top level of the TCP protocol module. Herein are the
TCP initialization, "interprocess communication" between parts of
the TCP, etc.
* SIGNAL ... 3 ...... Signal a TCP process to run
SIGNL0 ... 4 ...... Guts of SIGNAL
* TCPPRC ... 5 ...... Top level of TCP processing
* TCPCHK ... 6 ...... Set next TCP wakeup time
TCPRUN ... 7 ...... Run any TCP processes that are due
8 ...... Process table
DQTASK ... 9 ...... Remove a TCB from process input queue
* TCPTSK ... 10 ...... Run a TCP task on a particular TCB
* TCPINI ... 11 ...... Initialize entire TCP
!
; SIGNAL Cause a process to run.
;T1/ (Extended) Target process ID
;T2/ 0 or delta in milliseconds
;TCB/ (Extended) Locked Connection Block
;
; CALL SIGNAL
;Ret+1: Always
SIGNAL::TEMP <LCK,FN,PRC,DL>
DMOVEM T1,PRC
ADD DL,TODCLK ; Compute deadline
XMOVEI LCK,PRCLCK(PRC) ; Pointer to lock cell of process
XMOVEI FN,SIGNL0 ; Function
; PRC and DL have args to SIGNL0
CALL LCKCAL ; Lock the lock and call the function
RESTORE
RET
; SIGNL0 Guts of the Signal
;T1/ (Extended) Process block (locked)
;T2/ Wakeup TODCLK
;TCB/ (Extended) Connection block (locked)
; NOINT
; CALL SIGNL0
;Ret+1: Always
SIGNL0: LOCAL <PRC,DL,SAVTCB>
DMOVEM T1,PRC ; Save Process and Deadline
MOVEM TCB,SAVTCB ; Save the signalee
MOVE T3,TODCLK ; Now in milliseconds
MOVEM T3,PRCSGT(PRC) ; Set time of most recent signal
SKIPN @PRCQOF(PRC) ;@TCBQxx(TCB) This TCB already Q'd for task?
JRST SIGNL1 ; No. Just insert in queue.
XMOVEI T1,@PRCQOF(PRC) ;@TCBQxx(TCB) Get pointer to queue in the TCB
CAML DL,@PRCWOF(PRC) ;@TCBTxx(TCB) Compare with deadline already set
JRST SIGNL5 ; Leave in current position.
CALL DQ ; Sooner. Dequeue so it can be inserted
SIGNL1: MOVEM DL,@PRCWOF(PRC) ;@TCBTxx(TCB) NB double idx, here and elsewhere
MOVE T2,PRCQ(PRC) ; Pointer to input queue head
MOVE T3,PRCQOF(PRC) ; Get offset to queue in TCB
SIGNL2: LOAD T2,QNEXT,(T2) ; Get next TCB on input queue
SETSEC T2,INTSEC ; Make extended address
CAMN T2,PRCQ(PRC) ; Back to head?
JRST SIGNL4 ; Yes. Append to end of queue.
MOVE TCB,T2 ; Make right for indirect index
SUBI TCB,0(T3) ; Make TCB point to base of block
CAML DL,@PRCWOF(PRC) ;@TCBTxx(TCB) Found place to insert?
JRST SIGNL2 ; No. Scan more of queue
SIGNL4: MOVE TCB,SAVTCB ; Point TCB at the signalee
XMOVEI T1,@PRCQOF(PRC) ; Get pointer to queue in that TCB
CALL NQ ; And queue it up
SIGNL5: MOVE TCB,PRCQ(PRC) ; Pointer to input queue head
LOAD TCB,QNEXT,(TCB) ; Get first TCB on the queue
SUB TCB,PRCQOF(PRC) ; Make into standard TCB pointer
SETSEC TCB,INTSEC ; Make extended address
MOVE T1,@PRCWOF(PRC) ;@TCBTxx(TCB) Get wakeup time of 1st TCB on Q
MOVEM T1,PRCWAK(PRC) ; That is new wakeup for process
MOVE TCB,SAVTCB ; Restore TCB pointer for caller
CAMG T1,TODCLK ; Wakeup already gone by?
AOS TCPFLG ; Yes. Ensure that we keep running.
AOS INTFLG ; Cause Internet fork run TCPCHK
RESTORE
RET
; TCPPRC TCP processing
; (No args)
;
; CALL TCPPRC (From Internet fork)
;Ret+1: Always.
TCPPRC::SETZM TCPFLG ; Clear run request
SKIPE INTSVR ; Internet level needs space badly?
SETZM BG+PRCWAK ; Yes. Make BG scavenge what it can
XMOVEI T1,IP ; Select Input Processor
MOVE T2,TCPIPQ ; (Ext) Ptr to TCP input queue head
LOAD T3,QNEXT,(T2) ; Get first thing on the queue
CAIE T3,0(T2) ; Empty if that is the head.
CALL TCPTSK ; Process any available input packets
CALL TCPRUN ; Run all the other "processes"
XMOVEI T1,BG ; Ptr to Background Process
MOVE T2,PRCWAK(T1) ; Wakeup time for BG
CAMG T2,TODCLK ; Due for a run?
CALL TCPTSK ; Yes. Run BG.
CALL TVTOPR ; Operate TCP Virtual Terminals
SKIPE TCPFLG ; Further work to do?
JRST TCPPRC ; Yes.
RET
; TCPCHK Periodic check on TCP
;T1/ A TODCLK to be min'd against
;
; CALL TCPCHK ; From Internet fork
;Ret+1: Always. T1 as min of arg and next TCP check time
; TCPTIM set to next run time
TCPCHK::LOCAL <TOD>
MOVEM T1,TOD
MOVE T1,TODCLK ; Now.
ADD T1,TCPCKT ; Check again in 10 seconds
SKIPN TCPON ; Is the TCP on right now?
JRST TCPCH9 ; No.
MOVSI T2,-NPROCS ; Set to scan process table
TCPCH1: MOVE T3,PRCTAB(T2) ; Get pointer to process block
SKIPL T4,PRCWAK(T3) ; Avoid ones which aren't scheduled
CAML T4,T1 ; Less than current best min?
CAIA ; No.
MOVE T1,T4 ; Yes. Take the new value
AOBJN T2,TCPCH1 ; Loop over all processes in the table
SKIPL T4,BG+PRCWAK ; Special case background
CAML T4,T1
CAIA
MOVE T1,T4
TCPCH9: MOVEM T1,TCPTIM ; Save for scheduler test
CAMLE T1,TOD ; Min against arg
MOVE T1,TOD
RESTORE
RET
; TCPRUN Run all the TCP tasks
; Each process has an input queue of TCBs. TCPRUN scans all "processes"
; and for each with a non-empty queue, calls the approriate routine for
; each TCB on the queue. The new wake up time is set into the process
; block.
; CALL TCPRUN
;Ret+1: Always.
TCPRUN: LOCAL <I,PRC>
PUSH P,TCB
MOVSI I,-NPROCS ; Set to scan all processes
TCPRU1: MOVE PRC,PRCTAB(I) ; Get pointer to process block
TCPRU2: SKIPGE T1,PRCWAK(PRC) ; Get the wakeup time for this one
JRST TCPRU9 ; No run needed
MOVE T4,PRCQ(PRC) ; Get pointer to queue head
LOAD T3,QNEXT,(T4) ; Get first thing on the input queue
SETSEC T3,INTSEC ; Make extended address
CAMN T3,T4 ; Empty queue?
JRST TCPRU8 ; Yes. Cancel this process.
CAMLE T1,TODCLK ; Time to run?
JRST TCPRU9 ; No. Try next process
XMOVEI T1,PRCLCK(PRC) ; The lock to lock
XMOVEI T2,DQTASK ; The function to call
MOVE T3,PRC ; Process to work on
CALL LCKCAL ; Lock the lock and call the function
MOVE TCB,T1 ; Put in standard place
XMOVEI T1,TCBLCK(TCB) ; The lock on the TCB
XMOVEI T2,TCPTSK ; Subfunction to call
MOVE T3,PRC ; The task to run
CALL LCKCAL ; Lock the TCB and run the function
JRST TCPRU2 ; See if next TCB is due
TCPRU8: SETO T1, ; Empty queue means no wakeup
MOVEM T1,PRCWAK(PRC) ; Set into process block
TCPRU9: AOBJN I,TCPRU1 ; Loop over all processes in table
POP P,TCB
RESTORE
RET
; Table of process block pointers:
PRCTAB: IFIW!RA ; Reassembler
IFIW!PZ ; Packetizer
IFIW!RX ; Retransmitter
IFIW!DG ; Delayed Actions
NPROCS==.-PRCTAB
; Note that BG is special in that it does not have an input queue
; and that it must lock TCBH while it is running. IP is also special
; because it is driven by packets arriving from the network.
; DQTASK removes a TCB from a task input queue and resets the wakeup
; time for that task
;
;T1/ Process block pointer
; NOINT
; CALL DQTASK
;Ret+1: Always. T1 has pointer to TCB.
DQTASK: LOCAL <PRC,PROCQ>
PUSH P,TCB
MOVEM T1,PRC
MOVE PROCQ,PRCQ(PRC) ; Pointer to input queue
LOAD TCB,QNEXT,(PROCQ) ; Get 1st item on the queue
SETSEC TCB,INTSEC ; Make extended address
MOVE T1,TCB ; This the one to return
CALL DQ ; Remove it from the queue
MOVE T2,PRCQOF(PRC) ; Get offset to queue word in TCB
SUBI T1,0(T2) ; Get standard TCB pointer
LOAD TCB,QNEXT,(PROCQ) ; Get 1st item on remaining queue
SETSEC TCB,INTSEC ; Make extended address
CAMN TCB,PROCQ ; Is the queue now empty?
JRST DQTAS8 ; Yes.
SUBI TCB,0(T2) ; Get pointer to base of TCB
SKIPA T2,@PRCWOF(PRC) ; Note double index by PRC and TCB
DQTAS8: SETO T2, ; No need to run
MOVEM T2,PRCWAK(PRC) ; Set new wakeup
POP P,TCB
RESTORE
RET
; TCPTSK(Process) Call the process routine and do accounting
;T1/ (Extended) Process block pointer
;TCB/ (Extended) Locked Connection Block, unless IP or BG being run
;
; CALL TCPTSK
;Ret+1: Always
TCPTSK::LOCAL <PRC>
MOVEM T1,PRC
MOVEM PRC,PROC ; Indicate who is running now.
SKIPN STATF ; Taking statistics right now?
JRST TCPTS9 ; No. Just call the function
XMOVEI T1,BG
XMOVEI T2,IP
CAME PRC,T1 ; Running Background?
CAMN PRC,T2 ; Running Input Processor?
JRST TCPTS8 ; Yes. Activate delay not defined
MOVEI T1,ACDLAY ; Select activation delay histogram
MOVE T2,TODCLK ; Now
SUB T2,PRCSGT(PRC) ; Time of most recent signal
CALL DOHIST ; Histogram that delta
TCPTS8:
MOVE T1,PRCTMR(PRC) ; Pointer to appropriate timer
MOVE T2,PRCROU(PRC) ; The routine to call
CALL TIMCAL ; Time the call
JRST TCPTSX
TCPTS9: CALL @PRCROU(PRC) ; Call the routine
TCPTSX: AOS TASKCT ; Count tasks run
AOS @PRCRNC(PRC) ; Count runs of this particular process
SETZM PROC ; Indicate nobody running now.
RESTORE
RET
; TCPINI Initialize TCP module
; (no args)
;
; CALL TCPINI (From INTINI)
;Ret+1: Always. TCP ready to run.
TCPINI::NOSKED
MOVEI T1,QSZ ; Size of a queue head
CALL GETBLK ; Get that amount of free storage
JUMPE T1,TCPINX ; Lose
MOVEM T1,TCPIPQ ; That is the TCP input queue
CALL INITQ ; Initialize it
CALL TBFINI ; Initialize Buffer Windows
CALL PZINI ; Initialize Packetizer
JUMPE T1,TCPINX ; Lose
CALL IPINI ; Initialize Input Processor
JUMPE T1,TCPINX ; Lose
CALL RAINI ; Initialize Reassembler
JUMPE T1,TCPINX ; Lose
CALL RXINI ; Initialize Retransmitter
JUMPE T1,TCPINX ; Lose
CALL DGINI ; Initialize Delayed Action Generator
JUMPE T1,TCPINX ; Lose
CALL BGINI ; Initialize Background Routine
JUMPE T1,TCPINX ; Lose
CALL USRINI ; Initialize User Interface
JUMPE T1,TCPINX ; Lose
CALL STSINI ; Initialize Statistics
CALL PPINI ; Initialize Packet Printer
CALL TCBINI ; Initialize TCB Hash table
JUMPE T1,TCPINX ; Lose
; All ok
SETZM TCPSID ; Clear TCP segment idents.
SETOM TCPIFG ; TCP has now been initialized
SETOM TCPON ; The TCP is now on
TCPINX: OKSKED
RET